package com.gz.spring.aop.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class VehicleProxyProvider {

    //target_vehicle表示真正要执行的对象
    //该对象的类实现了Vehicle接口
    private Vehicle target_vehicle;

    //构造器
    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }

    //编写一个方法，可以返回代理对象
    //public static Object newProxyInstance(ClassLoader loader,
    //                                          Class<?>[] interfaces,
    //                                          InvocationHandler h)
    //1. Proxy.newProxyInstance可以返回一个代理对象
    //2. ClassLoader loader类加载器
    //3. Class<?>[] interfaces将来要代理的对象的接口信息
    //4. InvocationHandler h 调用处理器/对象，有一个很重要的方法invoke

    public Vehicle getProxy() {
        //得到类加载器
        ClassLoader classLoader = target_vehicle.getClass().getClassLoader();

        //得到要代理的对象/被执行对象 的接口信息，底层是通过接口来完成调用
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();

        //创建InvocationHandler h
        //因为InvocationHandler是接口，不能被实例化，所以可以通过匿名对象的方式来创建该对象
        InvocationHandler invocationHandler=new InvocationHandler(){
            /**
             * @param proxy 代理对象(如ship、car)
             * @param method 通过代理对象调用的哪个方法
             * @param args 表示调用方法中的参数 如:.run(xx)中的xx
             * @return 表示.run(xx)执行后的结果
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("交通工具开始运行了");
                Object result = method.invoke(target_vehicle, args);
                System.out.println("交通工具结束运行了");
                return result;
            }
        };

        Vehicle vehicle = (Vehicle)Proxy.
                newProxyInstance(classLoader, interfaces, invocationHandler);

        return vehicle;
    }
}
